/**
 * 
 */
package za.co.sindi.oauth.core.service;

import za.co.sindi.oauth.core.annotation.Service;
import za.co.sindi.oauth.core.context.RequestContext;
import za.co.sindi.oauth.core.context.ResponseContext;
import za.co.sindi.oauth.core.result.Result;
import za.co.sindi.oauth.core.scanner.filter.TypeFilter;
import za.co.sindi.oauth.core.scanner.filter.impl.AnnotationTypeFilter;
import za.co.sindi.oauth.exception.ServiceException;
import za.co.sindi.oauth.server.config.RequestConfig;
import za.co.sindi.oauth.util.ApplicationUtil;

/**
 * This is a wrapper class for services annotated with {@link com.neurologic.oauth.core.annotation.Service} annotation.
 * 
 * @author Buhake Sindi
 * @since 12 April 2012
 *
 */
public class AnnotatedService extends InvokeableService {
	
	private static final TypeFilter SERVICE_ANNOTATION_TYPE_FILTER = new AnnotationTypeFilter(Service.class);
	private final String className;
	
	/**
	 * @param className
	 * @throws ClassNotFoundException 
	 */
	public AnnotatedService(final String className) throws ClassNotFoundException {
		super();
		if (className == null || className.isEmpty()) {
			throw new IllegalArgumentException("A class name may not be null or empty.");
		}
		
		this.className = className;
		actualClass = ApplicationUtil.applicationClass(className);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.service.Service#service(com.neurologic.oauth.server.config.RequestConfig, com.neurologic.oauth.core.context.RequestContext, com.neurologic.oauth.core.context.ResponseContext)
	 */
	@Override
	public Result service(RequestConfig config, RequestContext request, ResponseContext response) throws ServiceException {
		// TODO Auto-generated method stub
		//Check that we have the accurate service, (even though by now, we should)
		if (!SERVICE_ANNOTATION_TYPE_FILTER.match(actualClass)) {
			throw new ServiceException("Class '" + className +"' isn't annotated with @Service annotation.");
		}
		
		return super.service(config, request, response);
	}
}
